package com.analyse.stock.strategy;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.analyse.stock.annotation.StrategyType;
import com.analyse.stock.component.TradingBizAbstract;
import com.analyse.stock.constant.StockConstant;
import com.analyse.stock.enums.StrategyEnum;
import com.analyse.stock.form.PickStockQueryForm;
import com.analyse.stock.form.TradingForm;
import com.analyse.stock.model.*;
import com.analyse.stock.service.IStockExchange;
import com.analyse.stock.service.IStockInfo;
import com.analyse.stock.service.IStockKlineDaily;
import com.analyse.stock.service.IStrategyPoolService;
import com.analyse.stock.utils.PublicHolidayUtil;
import com.analyse.stock.utils.StockStringUtil;
import com.analyse.stock.vo.StrategyAnalyseResultVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.ta4j.core.BarSeries;
import org.ta4j.core.Rule;

import java.math.BigDecimal;
import java.time.LocalTime;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * T1 实时自动交易
 **/
@Slf4j
@Component
@StrategyType(strategy = StrategyEnum.T1_TRADING_STRATEGY)
public class T1TradingIStrategy implements IStrategy {

    @Autowired
    private IStockInfo istockInfo;

    @Autowired
    private IStockExchange stockExchange;

    @Autowired
    private IStrategyPoolService strategyPoolService;

    @Autowired
    private IStockKlineDaily stockKlineDaily;

    @Override
    public StrategyAnalyseResultVO run(String paramJson)  {
        if (StringUtils.isBlank(paramJson)) {
            return null;
        }
        PickStockQueryForm queryForm = JSONObject.parseObject(paramJson, PickStockQueryForm.class);
        StockInfoModel stockModel = istockInfo.getStockInfo(queryForm.getStockCode());
        if(Objects.isNull(stockModel)){
            return null;
        }
        //读取股票所属的交易所
        StockExchangeModel exchangeModel =
                stockExchange.getStockExchange(stockModel.getCountryCode(),stockModel.getExchangeCode());
        if(Objects.isNull(exchangeModel)){
            return null;
        }
        boolean isTradingDate = PublicHolidayUtil.isTradingDate(stockModel.getExchangeCode(), DateUtil.date());
        if(!isTradingDate){
            return null;
        }
        StrategyPoolModel strategyPool = strategyPoolService.getStrategyPoolByCode(StrategyEnum.T1_TRADING_STRATEGY.getCode());

        String userId = "admin";
        String accountId = "admin";
        TradingForm tradingForm = TradingForm.me(userId,accountId,stockModel,strategyPool);
        new TradingBizAbstract<StrategyAnalyseResultVO>(tradingForm){
            @Override
            public boolean verify(Date now) {
                return PublicHolidayUtil.isTradingTime(now,
                        StockStringUtil.getTradingTimeFun(exchangeModel.getLocalOpen(),exchangeModel.getLocalClose()));
            }
            @Override
            public boolean isTrading(Date now) {
                int closeHour = DateUtil.hour(DateUtil.parse(exchangeModel.getLocalClose(), DatePattern.NORM_TIME_FORMAT),true);
                int closeMinute = DateUtil.minute(DateUtil.parse(exchangeModel.getLocalClose(), DatePattern.NORM_TIME_FORMAT));
                return PublicHolidayUtil.isTradingTime(now, localTime->{
                    LocalTime closeTime = LocalTime.of(closeHour, closeMinute);
                    return localTime.isBefore(closeTime);
                });
            }

            @Override
            public UserPositionInfoModel getUserPositionData(String userId,String accountId,String stockCode) {
                return null;
            }

            @Override
            public List<StockKlineDailyModel> getKlineData(PickStockQueryForm conForm) {
                return stockKlineDaily.getStockKlineDailyList(
                        conForm.getStockCode(),conForm.getStartDate(),conForm.getEndDate());
            }

            @Override
            public StockCoreInfoModel pullRealTimeData(String stockCode) {
                return istockInfo.pullLatestStockInfo(stockCode);
            }

            @Override
            public StrategyAnalyseResultVO execSellRule(BarSeries barSeries,UserPositionInfoModel positionData,
                                                        List<Rule> sellRule, StockCoreInfoModel realTimeData) {
                //TODO 执行sell卖出策略

                UserFundInfoModel fund = StockConstant.FUND_ACCOUNT_MAP.get(realTimeData.getStockCode());
                UserFundInfoModel.sell(fund,realTimeData.getStockCode());
                return null;
            }

            @Override
            public StrategyAnalyseResultVO execBuyRule(BarSeries barSeries,UserPositionInfoModel positionData,
                                                       List<Rule> buyRule, StockCoreInfoModel realTimeData) {

                BigDecimal bugAmt = BigDecimal.valueOf(8123.42);
                UserFundInfoModel fund = StockConstant.FUND_ACCOUNT_MAP.get(realTimeData.getStockCode());
                UserFundInfoModel.buyBefore(fund,realTimeData.getStockCode(),bugAmt);

                //下委托买单  //TODO 执行buy买入出策略

                //下单成功后
                UserFundInfoModel.buyAfter(fund,realTimeData.getStockCode(),bugAmt);
                return null;
            }
        }.exec();
        return null;
    }
}
